home *** CD-ROM | disk | FTP | other *** search
- /* This file is for functions dealing with execution of
- commands, command lines, buffers, files and startup files
-
- written 1986 by Daniel Lawrence */
-
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
-
- #if MEGAMAX & ST520
- overlay "exec"
- #endif
-
- #if DEBUGM
- char outline[NSTRING]; /* global string to hold debug line text */
- #endif
-
- /* namedcmd: execute a named command even if it is not bound */
-
- namedcmd(f, n)
-
- int f, n; /* command arguments [passed through to command executed] */
-
- {
- register (*kfunc)(); /* ptr to the requexted function to bind to */
- int (*getname())();
-
- /* prompt the user to type a named command */
- mlwrite(": ");
-
- /* and now get the function name to execute */
- kfunc = getname();
- if (kfunc == NULL) {
- mlwrite("[No such function]");
- return(FALSE);
- }
-
- /* and then execute the command */
- return((*kfunc)(f, n));
- }
-
- /* execcmd: Execute a command line command to be typed in
- by the user */
-
- execcmd(f, n)
-
- int f, n; /* default Flag and Numeric argument */
-
- {
- register int status; /* status return */
- char cmdstr[NSTRING]; /* string holding command to execute */
-
- /* get the line wanted */
- if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
- return(status);
-
- execlevel = 0;
- return(docmd(cmdstr));
- }
-
- /* docmd: take a passed string as a command line and translate
- it to be executed as a command. This function will be
- used by execute-command-line and by all source and
- startup files. Lastflag/thisflag is also updated.
-
- format of the command line is:
-
- {# arg} <command-name> {<argument string(s)>}
-
- Directives start with a "!" and include:
-
- !endm End a macro
- !if (cond) conditional execution
- !else
- !endif
- !return Return (terminating current macro)
- !goto <label> Jump to a label in the current macro
-
- Line Labels begin with a "*" in column 1, like:
-
- *LBL01
- */
-
- docmd(cline)
-
- char *cline; /* command line to execute */
-
- {
- register int f; /* default argument flag */
- register int n; /* numeric repeat value */
- register int i;
- int (*fnc)(); /* function to execute */
- int status; /* return status of function */
- int oldcle; /* old contents of clexec flag */
- int llen; /* length of cline */
- int force; /* force TRUE result? */
- char *tmp; /* tmp pointer into cline */
- struct LINE *lp; /* a line pointer */
- char *oldestr; /* original exec string */
- char token[NSTRING]; /* next token off of command line */
- int (*fncmatch())();
- #if DEBUGM
- /* if $debug == TRUE, every line to execute
- gets echoed and a key needs to be pressed to continue
- ^G will abort the command */
- register char *sp; /* pointer into buf to expand %s */
-
- if (macbug) {
- strcpy(outline, "<<<");
- #if 1 /* debug if levels */
- strcat(outline, itoa(execlevel));
- strcat(outline, ":");
- #endif
- strcat(outline, cline);
- strcat(outline, ">>>");
-
- /* change all '%' to ':' so mlwrite won't expect arguments */
- sp = outline;
- while (*sp) {
- if (*sp++ == '%')
- *(sp-1) = ':';
- }
-
- /* write out the debug line */
- mlwrite(outline);
- update(TRUE);
-
- /* and get the keystroke */
- if (tgetc() == 7) {
- mlwrite("[Macro aborted]");
- return(FALSE);
- }
- }
- #endif
-
- /* dump comments here */
- if (*cline == ';')
- return(TRUE);
-
- /* eat leading spaces */
- while (*cline == ' ' || *cline == '\t')
- ++cline;
-
- /* check to see if this line turns macro storage off */
- if (cline[0] == '!' && strncmp(&cline[1], "endm", 4) == 0) {
- mstore = FALSE;
- bstore = NULL;
- return(TRUE);
- }
-
- /* if macro store is on, just salt this away */
- if (mstore) {
- /* allocate the space for the line */
- llen = strlen(cline);
- if ((lp=lalloc(llen)) == NULL) {
- mlwrite("Out of memory while storing macro");
- return (FALSE);
- }
-
- /* copy the text into the new line */
- for (i=0; i<llen; ++i)
- lputc(lp, i, cline[i]);
-
- /* attach the line to the end of the buffer */
- bstore->b_linep->l_bp->l_fp = lp;
- lp->l_bp = bstore->b_linep->l_bp;
- bstore->b_linep->l_bp = lp;
- lp->l_fp = bstore->b_linep;
- return (TRUE);
- }
-
- /* dump labels here */
- if (*cline == '*')
- return(TRUE);
-
- force = FALSE;
- oldestr = execstr; /* save last ptr to string to execute */
- execstr = cline; /* and set this one as current */
-
- /* process directives */
- if (*cline == '!') {
- /* save directive location and skip it */
- tmp = cline;
- while (*execstr && *execstr != ' ' && *execstr != '\t')
- ++execstr;
-
- if (tmp[1] == 'f' && tmp[2] == 'o') {
- force = TRUE;
- goto do001;
-
- } else if (tmp[1] == 'i' && tmp[2] == 'f') {
-
- /* IF directive */
- /* grab the value of the logical exp */
- if (execlevel == 0) {
- if ((status = macarg(token)) != TRUE) {
- execstr = oldestr;
- return(status);
- }
- status = stol(token);
- } else
- status = TRUE;
-
- if (status) {
-
- /* IF (TRUE) */
- if (execlevel != 0)
- ++execlevel;
- } else {
-
- /* IF (FALSE) */
- ++execlevel;
- }
-
- } else if (tmp[1] == 'e' && tmp[2] == 'l') {
-
- /* ELSE directive */
- if (execlevel == 1)
- --execlevel;
- else if (execlevel == 0 )
- ++execlevel;
-
- } else if (tmp[1] == 'e' && tmp[2] == 'n') {
-
- /* ENDIF directive */
- if (execlevel)
- --execlevel;
-
- } else if (tmp[1] == 'r' && tmp[2] == 'e') {
-
- /* RETURN directive */
- execstr = oldestr;
- if (execlevel)
- return(TRUE);
- else
- return(RET);
-
- } else if (tmp[1] == 'g' && tmp[2] == 'o') {
-
- /* GOTO directive */
- /* .....only if we are currently executing */
- if (execlevel) {
- execstr = oldestr;
- return(TRUE);
- }
-
- while (*execstr == ' ' || *execstr == '\t')
- ++execstr;
- strncpy(golabel, execstr, NPAT - 1);
- return(GOLINE);
-
- } else {
- mlwrite("%%Unknown Directive");
- return(FALSE);
- }
-
- /* restore execstr and exit */
- execstr = oldestr;
- return(TRUE);
- }
-
- do001: /* if we are scanning and not executing..go back here */
- if (execlevel) {
- execstr = oldestr;
- return(TRUE);
- }
-
- /* first set up the default command values */
- f = FALSE;
- n = 1;
- lastflag = thisflag;
- thisflag = 0;
-
- if ((status = macarg(token)) != TRUE) { /* and grab the first token */
- execstr = oldestr;
- return(status);
- }
-
- /* process leadin argument */
- if (gettyp(token) != TKCMD) {
- f = TRUE;
- n = atoi(getval(token));
-
- /* and now get the command to execute */
- if ((status = macarg(token)) != TRUE) {
- execstr = oldestr;
- return(status);
- }
- }
-
- /* and match the token to see if it exists */
- if ((fnc = fncmatch(token)) == NULL) {
- mlwrite("[No such Function]");
- execstr = oldestr;
- return(FALSE);
- }
-
- /* save the arguments and go execute the command */
- oldcle = clexec; /* save old clexec flag */
- clexec = TRUE; /* in cline execution */
- status = (*fnc)(f, n); /* call the function */
- cmdstatus = status; /* save the status */
- if (force) /* force the status */
- status = TRUE;
- clexec = oldcle; /* restore clexec flag */
- execstr = oldestr;
- return(status);
- }
-
- /* token: chop a token off a string
- return a pointer past the token
- */
-
- char *token(src, tok)
-
- char *src, *tok; /* source string, destination token string */
-
- {
- register int quotef; /* is the current string quoted? */
-
- /* first scan past any whitespace in the source string */
- while (*src == ' ' || *src == '\t')
- ++src;
-
- /* scan through the source string */
- quotef = FALSE;
- while (*src) {
- /* process special characters */
- if (*src == '~') {
- ++src;
- if (*src == 0)
- break;
- switch (*src++) {
- case 'r': *tok++ = 13; break;
- case 'n': *tok++ = 10; break;
- case 't': *tok++ = 9; break;
- case 'b': *tok++ = 8; break;
- case 'f': *tok++ = 12; break;
- default: *tok++ = *(src-1);
- }
- } else {
- /* check for the end of the token */
- if (quotef) {
- if (*src == '"')
- break;
- } else {
- if (*src == ' ' || *src == '\t')
- break;
- }
-
- /* set quote mode if qoute found */
- if (*src == '"')
- quotef = TRUE;
-
- /* record the character */
- *tok++ = *src++;
- }
- }
-
- /* terminate the token and exit */
- if (*src)
- ++src;
- *tok = 0;
- return(src);
- }
-
- macarg(tok) /* get a macro line argument */
-
- char *tok; /* buffer to place argument */
-
- {
- int savcle; /* buffer to store original clexec */
- int status;
-
- savcle = clexec; /* save execution mode */
- clexec = TRUE; /* get the argument */
- status = nextarg("", tok, NSTRING, ctoec('\n'));
- clexec = savcle; /* restore execution mode */
- return(status);
- }
-
- /* nextarg: get the next argument */
-
- nextarg(prompt, buffer, size, terminator)
-
- char *prompt; /* prompt to use if we must be interactive */
- char *buffer; /* buffer to put token into */
- char *size; /* size of the buffer */
- int terminator; /* terminating char to be used on interactive fetch */
-
- {
- /* if we are interactive, go get it! */
- if (clexec == FALSE)
- return(getstring(prompt, buffer, size, terminator));
-
- /* grab token and advance past */
- execstr = token(execstr, buffer);
-
- /* evaluate it */
- strcpy(buffer, getval(buffer));
- return(TRUE);
- }
-
- /* storemac: Set up a macro buffer and flag to store all
- executed command lines there */
-
- storemac(f, n)
-
- int f; /* default flag */
- int n; /* macro number to use */
-
- {
- register struct BUFFER *bp; /* pointer to macro buffer */
- char bname[NBUFN]; /* name of buffer to use */
-
- /* must have a numeric argument to this function */
- if (f == FALSE) {
- mlwrite("No macro specified");
- return(FALSE);
- }
-
- /* range check the macro number */
- if (n < 1 || n > 40) {
- mlwrite("Macro number out of range");
- return(FALSE);
- }
-
- /* construct the macro buffer name */
- strcpy(bname, "[Macro xx]");
- bname[7] = '0' + (n / 10);
- bname[8] = '0' + (n % 10);
-
- /* set up the new macro buffer */
- if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
- mlwrite("Can not create macro");
- return(FALSE);
- }
-
- /* and make sure it is empty */
- bclear(bp);
-
- /* and set the macro store pointers to it */
- mstore = TRUE;
- bstore = bp;
- return(TRUE);
- }
-
- /* execbuf: Execute the contents of a buffer of commands */
-
- execbuf(f, n)
-
- int f, n; /* default flag and numeric arg */
-
- {
- register BUFFER *bp; /* ptr to buffer to execute */
- register int status; /* status return */
- char bufn[NBUFN]; /* name of buffer to execute */
-
- /* find out what buffer the user wants to execute */
- if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE)
- return(status);
-
- /* find the pointer to that buffer */
- if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
- mlwrite("No such buffer");
- return(FALSE);
- }
-
- /* and now execute it as asked */
- while (n-- > 0)
- if ((status = dobuf(bp)) != TRUE)
- return(status);
- return(TRUE);
- }
-
- /* dobuf: execute the contents of the buffer pointed to
- by the passed BP */
-
- dobuf(bp)
-
- BUFFER *bp; /* buffer to execute */
-
- {
- register int status; /* status return */
- register LINE *lp; /* pointer to line to execute */
- register LINE *hlp; /* pointer to line header */
- register LINE *glp; /* line to goto */
- register int linlen; /* length of line to execute */
- register WINDOW *wp; /* ptr to windows to scan */
- char *eline; /* text of line to execute */
-
- /* clear IF level flags */
- execlevel = 0;
-
- /* starting at the beginning of the buffer */
- hlp = bp->b_linep;
- lp = hlp->l_fp;
- while (lp != hlp) {
- /* allocate eline and copy macro line to it */
- linlen = lp->l_used;
- if ((eline = malloc(linlen+1)) == NULL) {
- mlwrite("%%Out of Memory during macro execution");
- return(FALSE);
- }
- strncpy(eline, lp->l_text, linlen);
- eline[linlen] = 0; /* make sure it ends */
-
- /* trim leading whitespace */
- while (eline[0] == ' ' || eline[0] == '\t')
- strcpy(eline, &eline[1]);
-
- /* if it is not a comment, execute it */
- if (eline[0] != 0 && eline[0] != ';') {
- status = docmd(eline);
-
- /* if it is a !GOTO directive, deal with it */
- if (status == GOLINE) {
- linlen = strlen(golabel);
- glp = hlp->l_fp;
- while (glp != hlp) {
- if (*glp->l_text == '*' &&
- (strncmp(&glp->l_text[1], golabel,
- linlen) == 0)) {
- lp = glp;
- status = TRUE;
- }
- glp = glp->l_fp;
- }
- }
-
- if (status == GOLINE) {
- mlwrite("%%No such label");
- return(FALSE);
- }
-
- /* if it is a !RETURN directive...do so */
- if (status == RET) {
- free(eline);
- break;
- }
-
- /* check for a command error */
- if (status != TRUE) {
- /* look if buffer is showing */
- wp = wheadp;
- while (wp != NULL) {
- if (wp->w_bufp == bp) {
- /* and point it */
- wp->w_dotp = lp;
- wp->w_doto = 0;
- wp->w_flag |= WFHARD;
- }
- wp = wp->w_wndp;
- }
- /* in any case set the buffer . */
- bp->b_dotp = lp;
- bp->b_doto = 0;
- free(eline);
- execlevel = 0;
- return(status);
- }
- }
-
- /* on to the next line */
- free(eline);
- lp = lp->l_fp;
- }
-
- /* exit the current function */
- execlevel = 0;
- return(TRUE);
- }
-
- execfile(f, n) /* execute a series of commands in a file
- */
-
- int f, n; /* default flag and numeric arg to pass on to file */
-
- {
- register int status; /* return status of name query */
- char *fname[NSTRING]; /* name of file to execute */
-
- if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
- return(status);
-
- /* otherwise, execute it */
- while (n-- > 0)
- if ((status=dofile(fname)) != TRUE)
- return(status);
-
- return(TRUE);
- }
-
- /* dofile: yank a file into a buffer and execute it
- if there are no errors, delete the buffer on exit */
-
- dofile(fname)
-
- char *fname; /* file name to execute */
-
- {
- register BUFFER *bp; /* buffer to place file to exeute */
- register BUFFER *cb; /* temp to hold current buf while we read */
- register int status; /* results of various calls */
- char bname[NBUFN]; /* name of buffer */
-
- makename(bname, fname); /* derive the name of the buffer */
- if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
- return(FALSE);
-
- bp->b_mode = MDVIEW; /* mark the buffer as read only */
- cb = curbp; /* save the old buffer */
- curbp = bp; /* make this one current */
- /* and try to read in the file to execute */
- if ((status = readin(fname, FALSE)) != TRUE) {
- curbp = cb; /* restore the current buffer */
- return(status);
- }
-
- /* go execute it! */
- curbp = cb; /* restore the current buffer */
- if ((status = dobuf(bp)) != TRUE)
- return(status);
-
- /* if not displayed, remove the now unneeded buffer and exit */
- if (bp->b_nwnd == 0)
- zotbuf(bp);
- return(TRUE);
- }
-
- /* cbuf: Execute the contents of a numbered buffer */
-
- cbuf(f, n, bufnum)
-
- int f, n; /* default flag and numeric arg */
- int bufnum; /* number of buffer to execute */
-
- {
- register BUFFER *bp; /* ptr to buffer to execute */
- register int status; /* status return */
- static char bufname[] = "[Macro xx]";
-
- /* make the buffer name */
- bufname[7] = '0' + (bufnum / 10);
- bufname[8] = '0' + (bufnum % 10);
-
- /* find the pointer to that buffer */
- if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
- mlwrite("Macro not defined");
- return(FALSE);
- }
-
- /* and now execute it as asked */
- while (n-- > 0)
- if ((status = dobuf(bp)) != TRUE)
- return(status);
- return(TRUE);
- }
-
- cbuf1(f, n)
-
- {
- cbuf(f, n, 1);
- }
-
- cbuf2(f, n)
-
- {
- cbuf(f, n, 2);
- }
-
- cbuf3(f, n)
-
- {
- cbuf(f, n, 3);
- }
-
- cbuf4(f, n)
-
- {
- cbuf(f, n, 4);
- }
-
- cbuf5(f, n)
-
- {
- cbuf(f, n, 5);
- }
-
- cbuf6(f, n)
-
- {
- cbuf(f, n, 6);
- }
-
- cbuf7(f, n)
-
- {
- cbuf(f, n, 7);
- }
-
- cbuf8(f, n)
-
- {
- cbuf(f, n, 8);
- }
-
- cbuf9(f, n)
-
- {
- cbuf(f, n, 9);
- }
-
- cbuf10(f, n)
-
- {
- cbuf(f, n, 10);
- }
-
- cbuf11(f, n)
-
- {
- cbuf(f, n, 11);
- }
-
- cbuf12(f, n)
-
- {
- cbuf(f, n, 12);
- }
-
- cbuf13(f, n)
-
- {
- cbuf(f, n, 13);
- }
-
- cbuf14(f, n)
-
- {
- cbuf(f, n, 14);
- }
-
- cbuf15(f, n)
-
- {
- cbuf(f, n, 15);
- }
-
- cbuf16(f, n)
-
- {
- cbuf(f, n, 16);
- }
-
- cbuf17(f, n)
-
- {
- cbuf(f, n, 17);
- }
-
- cbuf18(f, n)
-
- {
- cbuf(f, n, 18);
- }
-
- cbuf19(f, n)
-
- {
- cbuf(f, n, 19);
- }
-
- cbuf20(f, n)
-
- {
- cbuf(f, n, 20);
- }
-
- cbuf21(f, n)
-
- {
- cbuf(f, n, 21);
- }
-
- cbuf22(f, n)
-
- {
- cbuf(f, n, 22);
- }
-
- cbuf23(f, n)
-
- {
- cbuf(f, n, 23);
- }
-
- cbuf24(f, n)
-
- {
- cbuf(f, n, 24);
- }
-
- cbuf25(f, n)
-
- {
- cbuf(f, n, 25);
- }
-
- cbuf26(f, n)
-
- {
- cbuf(f, n, 26);
- }
-
- cbuf27(f, n)
-
- {
- cbuf(f, n, 27);
- }
-
- cbuf28(f, n)
-
- {
- cbuf(f, n, 28);
- }
-
- cbuf29(f, n)
-
- {
- cbuf(f, n, 29);
- }
-
- cbuf30(f, n)
-
- {
- cbuf(f, n, 30);
- }
-
- cbuf31(f, n)
-
- {
- cbuf(f, n, 31);
- }
-
- cbuf32(f, n)
-
- {
- cbuf(f, n, 32);
- }
-
- cbuf33(f, n)
-
- {
- cbuf(f, n, 33);
- }
-
- cbuf34(f, n)
-
- {
- cbuf(f, n, 34);
- }
-
- cbuf35(f, n)
-
- {
- cbuf(f, n, 35);
- }
-
- cbuf36(f, n)
-
- {
- cbuf(f, n, 36);
- }
-
- cbuf37(f, n)
-
- {
- cbuf(f, n, 37);
- }
-
- cbuf38(f, n)
-
- {
- cbuf(f, n, 38);
- }
-
- cbuf39(f, n)
-
- {
- cbuf(f, n, 39);
- }
-
- cbuf40(f, n)
-
- {
- cbuf(f, n, 40);
- }
-
-
-